package com.caltco.cargo.ops.common.utils;


import cn.hutool.core.util.StrUtil;
import com.caltco.cargo.ops.common.annotation.ExcelColumn;
import com.caltco.cargo.ops.common.vo.ExportColumnVo;
import org.springframework.format.annotation.DateTimeFormat;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ExcelUtils {

    /**
     * 获取导出excel的自定义表头
     * @param fields
     * @return
     */
    public static Map<String,Object> getColumns(Field[] fields){
        Map<String,Object> columns = new MapUtils();

        for (Field field : fields){
            if (field.isAnnotationPresent(ExcelColumn.class)) {
                columns.put(field.getName(),field.getAnnotation(ExcelColumn.class).value());
            }

        }

        return columns;
    }

    public static List<ExportColumnVo> getColumns1(Field[] fields){
        List<ExportColumnVo> columns = new ArrayList<>();

        for (Field field : fields){
            if (field.isAnnotationPresent(ExcelColumn.class)) {
                ExportColumnVo exportColumnVo=new ExportColumnVo();
                exportColumnVo.setKey(field.getName());
                exportColumnVo.setTitle(field.getAnnotation(ExcelColumn.class).value());
                exportColumnVo.setHeight(Integer.valueOf(field.getAnnotation(ExcelColumn.class).height().isEmpty()?"0":field.getAnnotation(ExcelColumn.class).height()));
                exportColumnVo.setWidth(Integer.valueOf(field.getAnnotation(ExcelColumn.class).width().isEmpty()?"0":field.getAnnotation(ExcelColumn.class).width()));
                exportColumnVo.setType(field.getAnnotation(ExcelColumn.class).type());
                columns.add(exportColumnVo);
            }

        }

        return columns;
    }

    /**
     * 根据JSON获取导入的excel中的对象
     * @param clazz 反射对应的对象
     * @param item 传入的json对象集合
     * @return
     * @throws Exception
     */
    public static Object getExcelEntity(Class clazz, Map<String, Object> item) throws Exception{
        Object entity = clazz.newInstance();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ExcelColumn.class)) {
                for (Map.Entry<String, Object> entry : item.entrySet()) {
                    if (field.getAnnotation(ExcelColumn.class).value().equals(entry.getKey())) {
                        PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                        Method wM = pd.getWriteMethod();
                        wM.invoke(entity, item.get(entry.getKey()));
                        break;
                    }
                }
            }
        }
        return entity;
    }

    public static Object getExcelEntityDetail(Class clazz, Map<String, Object> item) throws Exception {
        Object entity = clazz.newInstance();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ExcelColumn.class)) {
                for (Map.Entry<String, Object> entry : item.entrySet()) {
                    if (field.getAnnotation(ExcelColumn.class).value().equals(entry.getKey())) {
                        if (StrUtil.isBlank(entry.getValue().toString())) {
                            break;
                        }

                        String typeName = field.getType().getName();
                        PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                        Method wM = pd.getWriteMethod();
                        if ("java.lang.String".equals(typeName)) {
                            wM.invoke(entity, entry.getValue().toString());
                            break;
                        } else if ("java.time.LocalDateTime".equals(typeName)) {
                            String timeStr = entry.getValue().toString();
                            String pattern;
                            if (field.isAnnotationPresent(DateTimeFormat.class)) {
                                // 获取实体类上的时间格式
                                pattern = field.getAnnotation(DateTimeFormat.class).pattern();
                            } else {
                                // 默认指定格式
                                pattern = "yyyy-MM-dd HH:mm:ss";
                            }
                            LocalDateTime time = LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern(pattern));
                            wM.invoke(entity, time);
                            break;
                        } else {
                            // 字段为数字的情况，调用对应类型的valueOf转换类型
                            Class<?> stringClass = Class.forName("java.lang.String");
                            Class<?> typeClass = Class.forName(typeName);
                            Method valueOf = typeClass.getMethod("valueOf", stringClass);
                            wM.invoke(entity, valueOf.invoke(null, entry.getValue().toString()));
                            break;
                        }
                    }
                }
            }
        }
        return entity;
    }


}
